// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2023 Spacemit Co., Ltd.
 *
 */

#include <linux/kernel.h>
#include "../../include/spacemit_dsi_common.h"
#include "../../include/spacemit_video_tx.h"
#include <linux/delay.h>

#define UNLOCK_DELAY 0

struct spacemit_mode_modeinfo icnl9951r_spacemit_modelist[] = {
	{
		.name = "1200x1920-60",
		.refresh = 60,
		.xres = 1200,
		.yres = 1920,
		.real_xres = 1200,
		.real_yres = 1920,
		.left_margin = 40,
		.right_margin = 40,
		.hsync_len = 4,
		.upper_margin = 32,
		.lower_margin = 180,
		.vsync_len = 4,
		.hsync_invert = 0,
		.vsync_invert = 0,
		.invert_pixclock = 0,
		.pixclock_freq = 87*1000,
		.pix_fmt_out = OUTFMT_RGB888,
		.width = 147,
		.height = 236,
	},
};

struct spacemit_mipi_info icnl9951r_mipi_info = {
	.height = 1920,
	.width = 1200,
	.hfp = 48,/* unit: pixel */
	.hbp = 48,
	.hsync = 4,
	.vfp = 180, /*unit: line*/
	.vbp = 32,
	.vsync = 4,
	.fps = 60,

	.work_mode = SPACEMIT_DSI_MODE_VIDEO, /*command_mode, video_mode*/
	.rgb_mode = DSI_INPUT_DATA_RGB_MODE_888,
	.lane_number = 4,
	.phy_bit_clock = 614400000,
	.phy_esc_clock = 51200000,
	.split_enable = 0,
	.eotp_enable = 0,

	.burst_mode = DSI_BURST_MODE_BURST,
};

static struct spacemit_dsi_cmd_desc icnl9951r_set_id_cmds[] = {
	{SPACEMIT_DSI_SET_MAX_PKT_SIZE, SPACEMIT_DSI_LP_MODE, UNLOCK_DELAY, 1, {0x01}},
};

static struct spacemit_dsi_cmd_desc icnl9951r_read_id_cmds[] = {
	{SPACEMIT_DSI_GENERIC_READ1, SPACEMIT_DSI_LP_MODE, UNLOCK_DELAY, 3, {0x04}},
};

static struct spacemit_dsi_cmd_desc icnl9951r_set_power_cmds[] = {
	{SPACEMIT_DSI_SET_MAX_PKT_SIZE, SPACEMIT_DSI_HS_MODE, UNLOCK_DELAY, 1, {0x1}},
};

static struct spacemit_dsi_cmd_desc icnl9951r_read_power_cmds[] = {
	{SPACEMIT_DSI_GENERIC_READ1, SPACEMIT_DSI_HS_MODE, UNLOCK_DELAY, 1, {0xA}},
};

static struct spacemit_dsi_cmd_desc icnl9951r_init_cmds[] = {
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   3, {0xF0,0x5A,0x59}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   3, {0xF1,0xA5,0xA6}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xB2,0x04,0x03,0x94,0x95,0x77,0x77,0x07,0x90,0x88,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0x11,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xB3,0xF3,0x01,0x02,0x09,0x8A,0x85,0x00,0x00,0x57,0x00,0x00,0x11,0x34,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x06,0x80,0x80,0x01,0x00,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xB4,0x0D,0x06,0x1A,0x1D,0x56,0x26,0x01,0xC7,0x33,0x33,0xAA,0x33,0x44,0x26,0x26,0x00,0x02,0x08,0x20,0x30,0x05,0x85,0x23,0x20,0x40,0x11,0x10,0x20,0x00,0x00,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xB5,0x00,0xA8,0xA9,0x26,0x09,0x25,0x27,0x2D,0x2D,0x1B,0x19,0x17,0x15,0x13,0x11,0x0F,0x0D,0x05,0x23,0x03,0x03,0x03,0x03,0x03,0xC0,0x00,0x01,0x50,0xFF,0xFF,0xE0,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xB6,0x00,0xA8,0xA9,0x26,0x08,0x24,0x27,0x2D,0x2D,0x1A,0x18,0x16,0x14,0x12,0x10,0x0E,0x0C,0x04,0x22,0x03,0x03,0x03,0x03,0x03,0xC0,0x00,0x01,0x50,0xFF,0xFF,0xE0,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xB7,0x0F,0x03,0xC0,0x00,0x01,0x50,0x0F,0x03,0xC0,0x00,0x01,0x50,0x55,0x55,0x55,0x55,0x55,0x50,0x55,0x55,0x55,0x55,0x55,0x50,0x03,0x03,0xC0,0x00,0x01,0x50,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xB8,0x0F,0x03,0xC0,0x00,0x01,0x50,0x0F,0x03,0xC0,0x00,0x01,0x50,0x55,0x55,0x55,0x55,0x55,0x50,0x55,0x55,0x55,0x55,0x55,0x50,0x03,0x03,0xC0,0x00,0x01,0x50,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xB9,0x01,0x55,0x55,0x55,0x55,0x55,0x50,0x55,0x55,0x55,0x55,0x55,0x50,0xFF,0xFF,0xFF,0xFF,0xFD,0x50,0xFF,0xFF,0xFF,0xFF,0xFD,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  16, {0xBB,0x01,0x02,0x03,0x0A,0x04,0x13,0x14,0x12,0x16,0x5C,0x00,0x15,0x16,0x03,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xBC,0xFE,0xF8,0xF0,0x00,0x00,0x00,0x00,0x04,0x00,0x05,0x80,0x02,0x24,0x00,0xB9,0x99,0x99,0x00,0xC4,0x09,0xC3,0x86,0x03,0x2E,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   8, {0xBD,0xED,0x23,0x42,0x52,0x52,0x1F,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xBE,0x75,0x43,0x7E,0x43,0x0A,0x88,0x58,0x33,0x33,0x33,0x93,0x03,0x18,0x18,0x00,0x00,0x00,0x00,0xB2,0xAF,0xB2,0xAF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  11, {0xBF,0x0C,0x19,0x0C,0x19,0x00,0x11,0x22,0x04,0x58,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  23, {0xC0,0x40,0x90,0x17,0x41,0x23,0x56,0xF7,0x8A,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0x00,0xCC,0x02,0x00,0x01,0xB3}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xC1,0x00,0xB4,0x00,0x1E,0x00,0x20,0x04,0x28,0x28,0x04,0xC7,0x80,0x05,0x12,0xC0,0x23,0x47,0xC0,0x10,0xFF,0x0F,0xE7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  2,  {0xC2,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xC3,0x00,0xFF,0x42,0x4D,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x97,0x10,0x10,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  15, {0xC4,0x0C,0x35,0x28,0x49,0x00,0x3F,0x00,0x50,0x00,0x1F,0x00,0xA3,0xF0,0xE7}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0xC5,0x03,0x13,0x10,0x57,0x5D,0x37,0x04,0x05,0x04,0x04,0x19,0x00,0xB4,0x2C,0x2B,0x2B,0xBB,0xAE,0x20,0x00,0x02,0x00,0x80,0x1D,0x15,0x06,0x13,0x64,0xFF,0x03,0x20,0xFF}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  30, {0xC7,0x76,0x54,0x32,0x22,0x34,0x56,0x77,0x77,0x20,0x76,0x54,0x32,0x22,0x34,0x56,0x77,0x77,0x20,0x42,0x00,0x21,0xFF,0xFF,0x04,0x04,0x03,0x0E,0x07,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0x80,0xE8,0xD5,0xB4,0x99,0x82,0x6D,0x5A,0x4A,0x3A,0x09,0xE3,0xC3,0xA2,0x84,0x69,0x3B,0x08,0xDA,0xAF,0xAC,0x83,0x5A,0x2E,0x00,0xD2,0x9A,0x77,0x49,0x3F,0x38,0x32,0x28}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0x81,0xE8,0xD2,0xAE,0x92,0x79,0x65,0x53,0x42,0x34,0x03,0xDC,0xBC,0x9B,0x7F,0x65,0x36,0x03,0xD6,0xAC,0xA9,0x81,0x58,0x2C,0xFF,0xD1,0x99,0x77,0x49,0x3F,0x38,0x32,0x28}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  33, {0x82,0xE8,0xD3,0xB1,0x95,0x7D,0x69,0x56,0x46,0x37,0x06,0xDF,0xBF,0x9E,0x81,0x67,0x38,0x05,0xD8,0xAD,0xAA,0x82,0x59,0x2D,0xFF,0xD1,0x99,0x77,0x49,0x3F,0x38,0x32,0x28}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  26, {0x83,0x09,0x1F,0x12,0x04,0x00,0x1F,0x12,0x04,0x00,0x1F,0x12,0x04,0x00,0x28,0x18,0x08,0x00,0x28,0x18,0x08,0x00,0x28,0x18,0x08,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,  28, {0x84,0xFF,0xFF,0xFA,0xAA,0x95,0x55,0x00,0x00,0x00,0xFF,0xFF,0xFA,0xAA,0x95,0x54,0x00,0x00,0x00,0xFF,0xFF,0xFA,0xAA,0x95,0x54,0x00,0x00,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   8, {0xC8,0x42,0x00,0x48,0xEC,0xE0,0x00,0x23}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   7, {0xD7,0x3F,0x04,0x0A,0x00,0x00,0x06}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   5, {0xD5,0x01,0x30,0xD4,0x10}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   3, {0xF1,0x5A,0x59}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   3, {0xF0,0xA5,0xA6}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   2, {0x35,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 120, 2, {0x11,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 10,  2, {0x29,0x00}},
	{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0,   2, {0xAC,0x05}},
};

static struct spacemit_dsi_cmd_desc icnl9951r_sleep_out_cmds[] = {
	{SPACEMIT_DSI_DCS_SWRITE,SPACEMIT_DSI_LP_MODE, 120, 1, {0x11}},
	{SPACEMIT_DSI_DCS_SWRITE,SPACEMIT_DSI_LP_MODE, 10,  1, {0x29}},
};

static struct spacemit_dsi_cmd_desc icnl9951r_sleep_in_cmds[] = {
	{SPACEMIT_DSI_DCS_LWRITE,SPACEMIT_DSI_LP_MODE, 0,   2, {0xAC,0x0A}},
	{SPACEMIT_DSI_DCS_SWRITE,SPACEMIT_DSI_LP_MODE, 10,  1, {0x28}},
	{SPACEMIT_DSI_DCS_SWRITE,SPACEMIT_DSI_LP_MODE, 120, 1, {0x10}},
};


struct lcd_mipi_panel_info lcd_icnl9951r = {
	.lcd_name = "icnl9951r",
	.lcd_id = 0x9951,
	.panel_id0 = 0x99,
	.power_value = 0x9c,
	.panel_type = LCD_MIPI,
	.width_mm = 147,
	.height_mm = 236,
	.dft_pwm_bl = 128,
	.set_id_cmds_num = ARRAY_SIZE(icnl9951r_set_id_cmds),
	.read_id_cmds_num = ARRAY_SIZE(icnl9951r_read_id_cmds),
	.init_cmds_num = ARRAY_SIZE(icnl9951r_init_cmds),
	.set_power_cmds_num = ARRAY_SIZE(icnl9951r_set_power_cmds),
	.read_power_cmds_num = ARRAY_SIZE(icnl9951r_read_power_cmds),
	.sleep_out_cmds_num = ARRAY_SIZE(icnl9951r_sleep_out_cmds),
	.sleep_in_cmds_num = ARRAY_SIZE(icnl9951r_sleep_in_cmds),
	//.drm_modeinfo = icnl9951r_modelist,
	.spacemit_modeinfo = icnl9951r_spacemit_modelist,
	.mipi_info = &icnl9951r_mipi_info,
	.set_id_cmds = icnl9951r_set_id_cmds,
	.read_id_cmds = icnl9951r_read_id_cmds,
	.set_power_cmds = icnl9951r_set_power_cmds,
	.read_power_cmds = icnl9951r_read_power_cmds,
	.init_cmds = icnl9951r_init_cmds,
	.sleep_out_cmds = icnl9951r_sleep_out_cmds,
	.sleep_in_cmds = icnl9951r_sleep_in_cmds,
	.bitclk_sel = 3,
	.bitclk_div = 1,
	.pxclk_sel = 2,
	.pxclk_div = 6,
};

int lcd_icnl9951r_init(void)
{
	int ret;

	ret = lcd_mipi_register_panel(&lcd_icnl9951r);
	return ret;
}
